package com.capgemini.fs.presentation.user.web.action;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DispatchAction;

import com.capgemini.fs.app.ekms.common.Constants;
import com.capgemini.fs.app.ekms.model.Group;
import com.capgemini.fs.app.ekms.persistence.util.QueryHelper;
import com.capgemini.fs.app.ekms.service.GroupService;
import com.capgemini.fs.presentation.common.util.CommonMethods;
import com.capgemini.fs.presentation.user.web.form.ModifyGroupForm;

public class ModifyGroupAction extends DispatchAction {

	private GroupService modifyGroupService;
	private String oldGroupName = null;
	private JSONObject jsonObject = new JSONObject();
	private PrintWriter out = null;
	private int pageSize = 10;

	public GroupService getModifyGroupService() {
		return modifyGroupService;
	}

	public void setModifyGroupService(GroupService modifyGroupService) {
		this.modifyGroupService = modifyGroupService;
	}

	public ActionForward validate(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) {
		String jsonString = CommonMethods.readJSONRequest(request);
		JSONObject jot = JSONObject.fromObject(jsonString);
		@SuppressWarnings("unused")
		String groupName = jot.getString("name");

		return null;
	}

	// Modify Groups
	public ActionForward modify(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) {
		String[] keyWords = { "Administrator", "Examinee", "Manager", "HR",
				"L & C","L& C","L &C","L&C", "Recruitment" };
		int errStatus = 0;
		HttpSession session = request.getSession();
		String userName = (String) session.getAttribute("username");

		String errMessage = new String();
		String jsonString = CommonMethods.readJSONRequest(request);
		JSONObject jot = JSONObject.fromObject(jsonString);
		JSONArray errors = new JSONArray();
		Group group = serializeGroup(jot);
		// Need to do [ check the integrality of this group ]
		// Update Group
		// Check whether group name is null
		if (null == group.getGroupName().trim()
				|| "".equalsIgnoreCase(group.getGroupName().trim())) {
			errStatus = 1;
			errMessage = "Please fill in the mandatory field Group Name!";
			request.setAttribute("Failed",
					"Please fill in the mandatory field Group Name!");
			JSONObject jo = new JSONObject();
			jo.put("error", errMessage);
			errors.add(jo);
		}
		// Check whether there is a same group name in the existing database
		try {
			List<Group> groupList = modifyGroupService.findAllGroup();
			for (Group groupl : groupList) {
				if (group.getGroupName().trim().equalsIgnoreCase(
						this.oldGroupName.trim())) {
					break;
				} else if (group.getGroupName().trim().equalsIgnoreCase(
						groupl.getGroupName().trim())) {
					List<Group> list = modifyGroupService.findAllGroup();
					request.setAttribute("groupList", list);
					errMessage = "The " + "\'" + group.getGroupName() + "\'"
							+ " already exist, please fill in again!";
					errStatus = 1;
					JSONObject jo = new JSONObject();
					jo.put("error", errMessage);
					errors.add(jo);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			List<Group> list = modifyGroupService.findAllGroup();
			request.setAttribute("groupList", list);
			errMessage = "Modified failed!";
			errStatus = 1;
			JSONObject jo = new JSONObject();
			jo.put("error", errMessage);
			errors.add(jo);
		}

		// Active or Inactive Users
		try {
			String isActiveOrInactiveUsers = jot
					.getString("isActiveOrInactiveUser");
			int status = jot.getInt("status");
			if (status == Constants.GROUP_STATUS_ACTIVE) {
				if ("Active".equalsIgnoreCase(isActiveOrInactiveUsers)) {
					modifyGroupService.activeGroupUser(group.getId(), userName);
				}
			} else if (status == Constants.GROUP_STATUS_INACTIVE) {
				if ("Inactive".equalsIgnoreCase(isActiveOrInactiveUsers)) {
					modifyGroupService.inactiveGroupUser(group.getId(),
							userName);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			List<Group> list = modifyGroupService.findAllGroup();
			request.setAttribute("groupList", list);
			request.setAttribute("failed", "Modified failed!");
			errStatus = 1;
			errMessage = e.getMessage();
			JSONObject jo = new JSONObject();
			jo.put("error", errMessage);
			errors.add(jo);
		}
		for (int i = 0; i < keyWords.length; i++) {
			if (group.getGroupName().trim().equalsIgnoreCase(keyWords[i])) {
				errStatus = 1;
				errMessage = "The " + "\'" + group.getGroupName() + "\'"
						+ " can not be the keyword as " + "\'" + keyWords[i]
						+ "\'" + ",please fill in again!";
				JSONObject jo = new JSONObject();
				jo.put("error", errMessage);
				errors.add(jo);
			}
		}
		if (errStatus != 1) {
			modifyGroupService.updateGroup(group);
			oldGroupName = group.getGroupName();
		}
		// Print JSONObject to request
		try {
			out = response.getWriter();
			JSONObject jso = new JSONObject();
			jso.put("groupId", group.getId());
			jso.put("gruopName", group.getGroupName().trim());
			jso.put("description", group.getDescription().trim());
			jso.put("active", group.getStatus());
			if (errStatus == 0) {
				jsonObject.put("notice", "Saved Successfully!");
			} else {
				jsonObject.put("notice", "");
			}
			jsonObject.put("status", errStatus);
			jsonObject.put("group", jso);
			jsonObject.put("errors", errors);
			out.print(jsonObject);
			out.flush();
			out.close();
			return null;
		} catch (Exception exc) {
			exc.printStackTrace();
			return null;
		}
	}

	// Modify Groups
	/**
	 * Method modify
	 * 
	 * @author CAVEE
	 * @param mapping
	 * @param form
	 * @param request
	 * @param response
	 * @return ActionForward
	 * */
	public ActionForward initModifyGroup(ActionMapping mapping,
			ActionForm form, HttpServletRequest request,
			HttpServletResponse response) {

		String jsonString = CommonMethods.readJSONRequest(request);
		JSONObject jot = JSONObject.fromObject(jsonString);
		oldGroupName = jot.getString("groupName");
		return null;
	}

	// Sort Group List
	public List<Group> sortGroupList(String sortType, String sortOrder,
			List<Group> list) {

		// Compare Group By Group Name
		Comparator<Group> compareByGroupName = new Comparator<Group>() {
			public int compare(Group g1, Group g2) {
				return g1.getGroupName().compareTo(g2.getGroupName());
			}
		};

		// Compare Group By Group Name
		Comparator<Group> compareByGroupStatus = new Comparator<Group>() {
			public int compare(Group g1, Group g2) {
				// return g1.getStatus().compareTo(g2.getStatus());
				if (!QueryHelper.isNullOrEmpty(g1.getStatus())
						&& !QueryHelper.isNullOrEmpty(g2.getStatus())) {
					if (g1.getStatus() < g2.getStatus()) {
						return -1;
					}
					if (g1.getStatus() > g2.getStatus()) {
						return 1;
					}
				}
				return 0;
			}
		};

		// Compare Group By Group Desc
		Comparator<Group> compareByGroupDesc = new Comparator<Group>() {
			public int compare(Group g1, Group g2) {
				return g1.getDescription().compareTo(g2.getDescription());
			}
		};

		if (null == sortType) {
			Collections.sort(list, compareByGroupName);
		}
		if ("name".equals(sortType)) {
			Collections.sort(list, compareByGroupName);
			if ("desc".equals(sortOrder)) {
				Collections.reverse(list);
			}
		}
		if ("status".equals(sortType)) {
			Collections.sort(list, compareByGroupStatus);
			if ("desc".equals(sortOrder)) {
				Collections.reverse(list);
			}
		}
		if ("desc".equals(sortType)) {
			Collections.sort(list, compareByGroupDesc);
			if ("desc".equals(sortOrder)) {
				Collections.reverse(list);
			}
		}
		return list;
	}

	// List all Groups
	public ActionForward listGroup(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) {
		String groupNameQuery = ((ModifyGroupForm) form).getGroupNameQuery();
		Integer groupActiveQuery = ((ModifyGroupForm) form)
				.getGroupActiveQuery();
		String sortType = ((ModifyGroupForm) form).getSortType();
		String sortOrder = ((ModifyGroupForm) form).getSortOrder();
		System.out.println("Group Name:  "+groupNameQuery);
		System.out.println("Active:  "+groupActiveQuery);
		List<Group> list;
		if (null == groupActiveQuery || 99 == groupActiveQuery) {
			list = modifyGroupService.queryGroup(groupNameQuery, null);
			System.out.println(list);
			groupActiveQuery = 99;
		} else {
			list = modifyGroupService.queryGroup(groupNameQuery,
					groupActiveQuery);
			System.out.println(list);
		}

		sortGroupList(sortType, sortOrder, list);
		if (null == sortType) {
			sortType = "name";
			sortOrder = "asce";
		}

		int totalRows = list.size();
		int nowPage = 1;
		int totalPage = getTotalPage(pageSize, totalRows);

		List<Group> data = new ArrayList<Group>();
		if (totalRows >= nowPage * pageSize) {
			for (int i = nowPage - 1; i < nowPage * pageSize; i++) {
				data.add(list.get(i));
			}
		} else {
			for (int i = nowPage - 1; i < totalRows; i++) {
				data.add(list.get(i));
			}
		}
		request.setAttribute("groupNameQuery", groupNameQuery);
		request.setAttribute("groupActiveQuery", groupActiveQuery);
		request.setAttribute("sortType", sortType);
		request.setAttribute("sortOrder", sortOrder);
		request.setAttribute("totalPage", nowPage + "/" + totalPage);
		request.setAttribute("nowPage", nowPage);
		request.setAttribute("groupList", data);
		request.setAttribute("totalPageNum", totalPage);
		request.setAttribute("statusMap", getStatusMap());
		return mapping.findForward("succ");
	}

	public HashMap<String, String> getStatusMap() {
		HashMap<String, String> map = new HashMap<String, String>();
		map.put("0", "Yes");
		map.put("1", "No");
		return map;
	}

	// Go to Next Page
	public ActionForward goToNextPage(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) {
		String groupNameQuery = ((ModifyGroupForm) form).getGroupNameQuery();
		Integer groupActiveQuery = ((ModifyGroupForm) form)
				.getGroupActiveQuery();
		String sortType = ((ModifyGroupForm) form).getSortType();
		String sortOrder = ((ModifyGroupForm) form).getSortOrder();
		List<Group> list;
		if (groupActiveQuery == 99 || null == groupActiveQuery) {
			list = modifyGroupService.queryGroup(groupNameQuery, null);
		} else {
			list = modifyGroupService.queryGroup(groupNameQuery,
					groupActiveQuery);
		}

		sortGroupList(sortType, sortOrder, list);
		int totalRows = list.size();

		ModifyGroupForm gmf = (ModifyGroupForm) form;
		int nowPage = gmf.getNowPage();
		int totalPage = getTotalPage(pageSize, totalRows);

		List<Group> data = new ArrayList<Group>();
		if (totalRows > (nowPage + 1) * pageSize) {
			for (int i = nowPage * pageSize; i < (nowPage + 1) * pageSize; i++) {
				data.add(list.get(i));
			}
		} else {
			for (int i = nowPage * pageSize; i < totalRows; i++) {
				data.add(list.get(i));
			}
		}
		nowPage = nowPage + 1;
		request.setAttribute("groupNameQuery", groupNameQuery);
		request.setAttribute("groupActiveQuery", groupActiveQuery);
		request.setAttribute("sortType", sortType);
		request.setAttribute("sortOrder", sortOrder);
		request.setAttribute("totalPage", nowPage + "/" + totalPage);
		request.setAttribute("nowPage", nowPage);
		request.setAttribute("groupList", data);
		request.setAttribute("totalPageNum", totalPage);
		request.setAttribute("statusMap", getStatusMap());
		return mapping.findForward("succ");
	}

	// Go to Next Page
	public ActionForward goToPreviousPage(ActionMapping mapping,
			ActionForm form, HttpServletRequest request,
			HttpServletResponse response) {
		String groupNameQuery = ((ModifyGroupForm) form).getGroupNameQuery();
		Integer groupActiveQuery = ((ModifyGroupForm) form)
				.getGroupActiveQuery();
		String sortType = ((ModifyGroupForm) form).getSortType();
		String sortOrder = ((ModifyGroupForm) form).getSortOrder();
		List<Group> list;
		if (groupActiveQuery == 99 || null == groupActiveQuery) {
			list = modifyGroupService.queryGroup(groupNameQuery, null);
		} else {
			list = modifyGroupService.queryGroup(groupNameQuery,
					groupActiveQuery);
		}

		sortGroupList(sortType, sortOrder, list);
		int totalRows = list.size();
		ModifyGroupForm gmf = (ModifyGroupForm) form;
		int nowPage = gmf.getNowPage();
		int totalPage = getTotalPage(pageSize, totalRows);

		List<Group> data = new ArrayList<Group>();
		if (nowPage - 2 >= 0) {
			for (int i = (nowPage - 2) * pageSize; i < (nowPage - 1) * pageSize; i++) {
				data.add(list.get(i));
			}
		}

		nowPage = nowPage - 1;
		request.setAttribute("groupNameQuery", groupNameQuery);
		request.setAttribute("groupActiveQuery", groupActiveQuery);
		request.setAttribute("sortType", sortType);
		request.setAttribute("sortOrder", sortOrder);
		request.setAttribute("totalPage", nowPage + "/" + totalPage);
		request.setAttribute("nowPage", nowPage);
		request.setAttribute("totalPageNum", totalPage);
		request.setAttribute("groupList", data);
		request.setAttribute("statusMap", getStatusMap());
		return mapping.findForward("succ");
	}

	// Go to Next Page
	public ActionForward goToTargetPage(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) {
		String groupNameQuery = ((ModifyGroupForm) form).getGroupNameQuery();
		Integer groupActiveQuery = ((ModifyGroupForm) form)
				.getGroupActiveQuery();
		String sortType = ((ModifyGroupForm) form).getSortType();
		String sortOrder = ((ModifyGroupForm) form).getSortOrder();
		List<Group> list;
		if (groupActiveQuery == 99 || null == groupActiveQuery) {
			list = modifyGroupService.queryGroup(groupNameQuery, null);
		} else {
			list = modifyGroupService.queryGroup(groupNameQuery,
					groupActiveQuery);
		}
		sortGroupList(sortType, sortOrder, list);
		int totalRows = list.size();
		ModifyGroupForm gmf = (ModifyGroupForm) form;
		int nowPage = gmf.getTargetPage();
		int totalPage = getTotalPage(pageSize, totalRows);
		List<Group> data = new ArrayList<Group>();

		if (nowPage > 0 && nowPage <= totalPage) {
			data = getTargetPageGroups(list, nowPage, totalRows);
		}

		request.setAttribute("groupNameQuery", groupNameQuery);
		request.setAttribute("groupActiveQuery", groupActiveQuery);
		request.setAttribute("sortType", sortType);
		request.setAttribute("sortOrder", sortOrder);
		request.setAttribute("totalPage", nowPage + "/" + totalPage);
		request.setAttribute("nowPage", nowPage);
		request.setAttribute("totalPageNum", totalPage);
		request.setAttribute("groupList", data);
		request.setAttribute("statusMap", getStatusMap());
		return mapping.findForward("succ");
	}

	// Go to some page
	public List<Group> getTargetPageGroups(List<Group> list, int targetNum,
			int totalNum) {
		List<Group> data = new ArrayList<Group>();
		if (targetNum * pageSize <= totalNum) {
			for (int i = (targetNum - 1) * pageSize; i < (targetNum * pageSize); i++) {
				data.add(list.get(i));
			}
		} else {
			for (int i = (targetNum - 1) * pageSize; i < totalNum; i++) {
				data.add(list.get(i));
			}
		}
		return data;
	}

	public int getTotalPage(int pageSize, int totalRows) {
		int totalPage;
		if (totalRows % pageSize > 0) {
			totalPage = totalRows / pageSize + 1;
		} else {
			totalPage = totalRows / pageSize;
		}
		return totalPage;
	}

	// Query Group
	public ActionForward queryGroup(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) {
		String groupNameQuery = ((ModifyGroupForm) form).getGroupNameQuery();
		Integer groupActiveQuery = ((ModifyGroupForm) form)
				.getGroupActiveQuery();
		if (groupActiveQuery == 99) {
			groupActiveQuery = null;
		}
		List<Group> list = modifyGroupService.queryGroup(groupNameQuery,
				groupActiveQuery);
		Collections.sort(list);
		return mapping.findForward("succ");
	}

	// Delete Group
	// will not be used
	public ActionForward delete(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) {
		try {
			@SuppressWarnings("unused")
			ModifyGroupForm modifyGroupForm = (ModifyGroupForm) form;
			// ((Object)
			// modifyGroupService).deleteGroupbyId(modifyGroupForm.getGroupId());
			List<Group> groupList = modifyGroupService.findAllGroup();
			request.setAttribute("groupList", groupList);
			request.setAttribute("Success", "Deleted Successfully!");
			return mapping.findForward("succ");
		} catch (Exception e) {
			e.printStackTrace();
			request.setAttribute("Failed", "Deleted Failed!");
			return mapping.findForward("failed");
		}
	}

	// serialize a Group from JSONObject
	public Group serializeGroup(JSONObject jo) {
		Group group = new Group();
		group.setId(jo.getInt("id"));
		Group oldGroup = modifyGroupService.findGoupByGroupId(jo.getInt("id"));
		group.setUsers(oldGroup.getUsers());
		group.setDescription(jo.getString("description"));
		group.setGroupName(jo.getString("groupName"));
		group.setStatus(jo.getInt("status"));
		return group;
	}

	// serialize a Group from Form
	public Group serializeGroup(ModifyGroupForm mgf) {
		Group group = new Group();
		group.setDescription(mgf.getGroupDesc());
		group.setGroupName(mgf.getGroupName());
		group.setId(mgf.getGroupId());
		return group;
	}
}
